home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / execbep.com / EXECBEEP.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-10-30  |  11.6 KB  |  329 lines

  1. name execbeep
  2.  
  3. dp        equ    dword ptr
  4. of        equ    offset
  5.  
  6. code        segment
  7.         assume    cs:code, ds:code
  8.         org     2CH
  9. ENV_SEG         dw      ?
  10.         org     80h
  11. TAIL_LENGTH     db  ?
  12.         org    100h
  13.  
  14. begin:        jmp    start
  15. prg_nam db 'EXECBEEP 3.0';
  16.  
  17. beep        proc            ; beep the speaker
  18.         push    ax        ; save
  19.         push    cx
  20.         in    al,97        ; get port values
  21.         and    al,0feh        ; turn speaker on
  22.         out    97,al
  23.         mov    cx,bx        ; cycles to cx
  24. more_sound:    push    cx        ; save cycles
  25.         xor    al,2        ; flip push/pull
  26.         out    97,al
  27.         mov    cx,dx        ; wait
  28. part1:        loop    part1
  29.         xor    al,2        ; flip push/pull
  30.         out    97,al
  31.         mov    cx,dx        ; wait
  32. part2:        loop    part2
  33.         pop    cx
  34.         loop    more_sound
  35.         pop    cx        ; restore
  36.         pop    ax
  37.         ret
  38. beep        endp
  39.  
  40. beep_low    proc
  41.         push    bx
  42.         push    dx
  43.         mov    bx,50        ; number of cycles
  44.         mov    dx,100        ; half cycle time
  45.         call    beep
  46.         pop    dx
  47.         pop    bx
  48.         ret
  49. beep_low    endp
  50.  
  51. beep_high    proc
  52.         push    bx
  53.         push    dx
  54.         mov    bx,100        ; number of cycles
  55.         mov    dx,50        ; half cycle time
  56.         call    beep
  57.         pop    dx
  58.         pop    bx
  59.         ret
  60. beep_high    endp
  61.  
  62. ; +++ EDR 2/27/88
  63.  
  64. space           db      ' ',0       ; just a space
  65. cr_lf           db      13,10,0     ; carriage return/line feed
  66.  
  67. tty_str         proc                ; show string in ES:SI, max of CX chars
  68.  
  69.                 jmp     short load  ; make sure string isn't null
  70.  
  71.         write:  mov     ah,0EH      ; write TTY service (char in AL)
  72.                 int     10H         ; kick BIOS
  73.  
  74.                 inc     si          ; point to next char
  75.                 dec     cx          ; and decrement count
  76.  
  77.         load:   mov     al,es:[si]  ; load char to show
  78.                 or      al,al       ; is it end of asciiz string?
  79.                 jz      done        ; yes
  80.                 cmp     cx,0        ; did we reach max char count?
  81.                 jnz     write       ; no- write it
  82.  
  83.         done:   ret
  84.  
  85. tty_str         endp
  86.  
  87. show_cmd        proc                    ; show the exec command line
  88.  
  89.                 push    ax              ; save the world
  90.                 push    cx
  91.                 push    dx
  92.                 push    si
  93.                 push    di
  94.                 push    es
  95.                 push    bx
  96.  
  97.                 mov     ax,ds           ; show command name from ds:dx
  98.                 mov     es,ax
  99.                 mov     si,dx
  100.                 mov     cx,64
  101.                 call    tty_str
  102.                 mov     ax,cs           ; followed by a space (just in case)
  103.                 mov     es,ax
  104.                 mov     si,offset space
  105.                 mov     cx,64
  106.                 call    tty_str
  107.  
  108.                 pop     bx              ; get original es:bx back
  109.                 pop     es
  110.                 push    es
  111.                 push    bx
  112.  
  113.                 mov     si,es:[bx+2]    ; set es:si to command arguments
  114.                 mov     ax,es:[bx+4]
  115.                 mov     es,ax
  116.  
  117.                 mov     cl,es:[si]      ; get char count in cx
  118.                 xor     ch,ch
  119.                 inc     si              ; skip to actual command chars
  120.                 call    tty_str         ; and show 'em
  121.  
  122.                 mov     ax,cs           ; skip up a line
  123.                 mov     es,ax
  124.                 mov     si,offset cr_lf
  125.                 mov     cx,64
  126.                 call    tty_str
  127.  
  128.                 pop     bx              ; restore the world
  129.                 pop     es
  130.                 pop     di
  131.                 pop     si
  132.                 pop     dx
  133.                 pop     cx
  134.                 pop     ax
  135.  
  136.                 ret                     ; back to caller
  137.  
  138. show_cmd        endp
  139.  
  140. ; --- EDR
  141. old_dos_int     label   dword           ; address
  142. old_int21       dw      2 dup(?)        ; former int 21h address
  143.  
  144. new_int21    proc    far
  145.         cmp    ah,4bh        ; EXEC function?
  146.         je    exec_beep    ; yes, beep, then call EXEC
  147.         cmp    ah,4dh        ; request to get return code?
  148.         je    retc_beep    ; yes, beep then get return code
  149.         jmp    dp cs:old_int21    ; no, pass it on
  150.  
  151. exec_beep:    call    beep_low    ; beep before EXEC
  152.                 call    show_cmd        ; show the command (EDR)
  153.         jmp    dp cs:old_int21    ; go do EXEC
  154.  
  155. retc_beep:    call    beep_high    ; beep after EXEC
  156.         jmp    dp cs:old_int21    ; go get return code
  157. new_int21    endp
  158.  
  159. END_OF_RES    label  word
  160.  
  161. HELP1           DB      'Cannot Uninstall - Did not find copy in memory$'
  162. HELP2           DB      'Cannot Install - Found copy already in memory$'
  163. help3           db      'ExecBeep Uninstalled$'
  164. help10          db      'Cannot Uninstall - INT 21 in wrong segment$'
  165. help11          db      'Error - Dos Free Memory function failed$'
  166. help12          db      'Error - Restore of old INT 21 failed$'
  167. help20          db      'ExecBeep Installed$'
  168.  
  169. alrdy_in_mem    db      0
  170. other_seg       dw      0
  171.  
  172. start:
  173.                 assume cs:code, ds:code, es:code, ss:code
  174. ; Deallocate environment block
  175.                 push    es
  176.                 mov     es,env_seg      ; get the segment from the PSP
  177.                 assume  es:nothing
  178.                 mov     ah,49h
  179.                 int     21h             ; call DOS release memory function
  180.                 pop     es
  181.                 assume  es:code
  182. ; check for other copies of this program in memory
  183. find_copies:
  184.                 xor     bx,bx
  185.                 mov     word ptr [begin],bx
  186.                 mov     ax,cs
  187. find_loop:
  188.                 inc     bx              ; check next segment
  189.                 mov     es,bx           ; use ES as segment pointer
  190.                 assume  es:nothing
  191.                 cmp     ax,bx           ; have we found ourselves?
  192.                 je      no_copies
  193.                 mov     si,offset begin ; si is the offset pointer
  194.                 mov     di,si           ; look the same place in both segs
  195.                 mov     cx,16           ; compare for 16 bytes
  196.                 cld                     ; increment pointers during compare
  197.                 repe    cmpsb           ; compabe bytes
  198.                 jne     find_loop       ; no match, keep looking
  199.                 inc     alrdy_in_mem    ; set already installed flag
  200. no_copies:
  201.                 mov     other_seg,es    ; save the segment for the copy
  202.                                         ;   that is already resident
  203.                 push    cs
  204.                 pop     es
  205.                 assume  es:code
  206.                 mov     di,offset tail_length ; use di to point to cmd line
  207.                 mov     ax,1234h        ; set ax to 1234h to indicate if
  208.                                         ;  a command was ever found
  209. find_command:
  210.                 inc     di              ;
  211.                 dec     tail_length     ;
  212.                 jl      find_command_done ; are we at end of command line?
  213.                 cmp     byte ptr [di],'u' ;
  214.                 je      un_install
  215.                 cmp     byte ptr [di],'U' ;
  216.                 je      un_install
  217.                 jmp     find_command    ;
  218. un_install:
  219.                 cmp     alrdy_in_mem,0  ; is there a resident copy?
  220.                 je      disp_help1      ; No, so we cannot uninstall
  221.                 assume  es:nothing
  222.                 mov     ax,other_seg    ; Make sure that ES points
  223.                 mov     es,ax           ;  to the segment of the resident copy.
  224.                 call    uninstall
  225.                 jc      help_routine    ; if CF set, error on uninstall
  226.                 mov     dx,offset help3 ; "ExecBeep Uninstalled"
  227.                 jmp     help_routine
  228.  
  229. ;-----------------------------------------------------------------------------
  230. ;Print help lines.
  231. ;-----------------------------------------------------------------------------
  232. DISP_HELP1:
  233.                 MOV    DX,OFFSET HELP1        ; Cannot Uninstall - not in memory
  234. HELP_ROUTINE:
  235.                 PUSH    DX                     ;Save offset to message
  236.                 MOV     AH,2                   ;Output a carrage return
  237.                 MOV     DL,10                  ;  to put a space between
  238.                 INT     21H                    ;  the messages.
  239.                 POP     DX                     ;Get back offset.
  240.                 MOV     AH,9                   ;DOS print string routine
  241.                 INT     21H
  242.                 mov     ax,4c00h
  243.                 int     21h
  244.  
  245. find_command_done:
  246.                 cmp     alrdy_in_mem,0
  247.                 je      carry_on
  248.                 mov     dx,offset help2
  249.                 jmp     help_routine
  250. carry_on:
  251.                 mov     ax,3521h        ; get int 21h
  252.         int    21h
  253.  
  254.         mov    old_int21,bx    ; store offset
  255.         mov    old_int21+2,es    ; store segment
  256.         mov    dx,of new_int21    ; ds:dx -> new int 21h
  257.         mov    ax,2521h
  258.         int    21h
  259.                 mov     dx,offset help20
  260.                 mov     ah,9
  261.                 int     21h
  262.                 mov     dx,of end_of_res     ; discard excess
  263.         add    dx,0fh
  264.         shr    dx,1
  265.         shr    dx,1
  266.         shr    dx,1
  267.         shr    dx,1
  268.         mov    ax,3100h    ; keep process
  269.         int    21h
  270.  
  271. ;-----------------------------------------------------------------------------
  272. ; UNINSTALL deallocates the memory block addressed by ES and restores the
  273. ; interrupt 21 vector displaced on installation.
  274. ;   Exit:   CF clear - program uninstalled
  275. ;           CF set   - can't uninstall
  276. ;-----------------------------------------------------------------------------
  277. UNINSTALL       PROC   NEAR
  278.                 ASSUME DS:CODE
  279.                 PUSH   ES
  280.                 MOV    AX,3521H               ;Get int 21 vector
  281.                 INT    21H
  282.                 MOV    AX,ES                  ;Compare vector segment with
  283.                 CMP    AX,OTHER_SEG           ;  segment of installed code.
  284.                 JNE    REMOVE_ERR1            ;If not the same, can't remove.
  285. ;-----------------------------------------------------------------------------
  286. ;Release the memory occupied by the program. ES already has proper segment.
  287. ;-----------------------------------------------------------------------------
  288.                 MOV    AH,49H                 ;DOS free memory function
  289.                 INT    21H
  290.                 JC     REMOVE_ERR2            ;If carry, error on removal
  291. ;-----------------------------------------------------------------------------
  292. ;Restore interrupt 21h vector.
  293. ;-----------------------------------------------------------------------------
  294.                 PUSH   DS
  295.                 LDS    DX,ES:[OLD_DOS_INT]    ;Get old vector from installed
  296.                 MOV    AX,2521H               ;  code.
  297.                 INT    21H                    ;Set int 21 to old vector.
  298.                 POP    DS
  299.                 JC     REMOVE_ERR3            ;If error, report and exit.
  300. ;-----------------------------------------------------------------------------
  301. ;Destroy the ASCII fingerprint that identifies the code and exit.
  302. ;-----------------------------------------------------------------------------
  303.                 NOT    WORD PTR ES:[BEGIN]
  304.                 CLC                           ;Clear error flag
  305. REMOVE_EXIT:
  306.                 POP    ES
  307.                 RET
  308. ;-----------------------------------------------------------------------------
  309. ;The program can't be uninstalled.  Set CF and exit.
  310. ;-----------------------------------------------------------------------------
  311. REMOVE_ERR1:
  312.                 MOV    DX,OFFSET HELP10       ;Point to error message.
  313.                 STC                           ;Set error flag
  314.                 JMP    SHORT REMOVE_EXIT
  315. remove_err2:
  316.                 mov    dx,offset help11
  317.                 stc
  318.                 jmp    short remove_exit
  319. remove_err3:
  320.                 mov    dx,offset help12
  321.                 stc
  322.                 jmp    short remove_exit
  323. UNINSTALL       ENDP
  324.  
  325.                 
  326.  
  327. code        ends
  328.         end    begin
  329.